package com.hunttown.mes.service;

import com.hunttown.mes.common.cache.Cache;
import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.common.utils.DateNomalUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.domain.LbsTerminal;
import com.hunttown.mes.domain.TransportUser;
import com.hunttown.common.domain.Query;
import com.hunttown.mes.dao.LbsTrackDao;
import com.hunttown.mes.domain.LbsTrack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * created by wangjunfu on 2021-07-05 11:06:23
 */
@Service
public class LbsTrackService {

    private final static Logger logger = LoggerFactory.getLogger(LbsTrackService.class);

    private final LbsTrackDao lbsTrackDao;
    private final LbsTerminalService lbsTerminalService;
    private final TransportUserService userService;
    private final AHelpService helpService;
    private final Cache jedisCache;

    @Autowired
    public LbsTrackService(LbsTrackDao lbsTrackDao, LbsTerminalService lbsTerminalService, TransportUserService userService, AHelpService helpService, Cache jedisCache) {
        this.lbsTrackDao = lbsTrackDao;
        this.lbsTerminalService = lbsTerminalService;
        this.userService = userService;
        this.helpService = helpService;
        this.jedisCache = jedisCache;
    }

    /**
     * 新增
     *
     * @param lbsTrack 实体对象
     * @return 最新插入id
     */
    public LbsTrack insert(LbsTrack lbsTrack) {
        //api接口传进来是有值的
        if (lbsTrack.getEntId() == null)
            lbsTrack.setEntId(helpService.getEnterpriseId());
        if (lbsTrack.getAdminId() == null)
            lbsTrack.setAdminId(0);
        if (lbsTrack.getCreateTime() == null)
            lbsTrack.setCreateTime(new Date());
        if (lbsTrack.getStopFlag() == null)
            lbsTrack.setStopFlag(0);
        if (lbsTrack.getDeleteFlag() == null)
            lbsTrack.setDeleteFlag(0);

        return lbsTrackDao.insert(lbsTrack);
    }

    /**
     * 根据ID修改数据信息
     *
     * @param lbsTrack 实体对象
     * @return True or False
     */
    public Boolean updateInfoById(LbsTrack lbsTrack) {
        if (lbsTrack.getEntId() == null) {
            lbsTrack.setEntId(helpService.getEnterpriseId());
        }
        return lbsTrackDao.updateInfoById(lbsTrack);
    }

    /**
     * 根据Query修改数据信息
     *
     * @param query 需要修改的字段 KV 格式
     * @return True or False
     */
    public Boolean updateInfoByQuery(Query query) {
        if (!query.containsKey("w_entId")) {
            query.put("w_entId", helpService.getEnterpriseId());
        }
        return lbsTrackDao.updateInfoByQuery(query);
    }

    /**
     * 根据ID获取记录信息
     *
     * @param id 主键id
     * @return 实体对象
     */
    public LbsTrack selectById(Integer id) {
        return lbsTrackDao.selectById(id, helpService.getEnterpriseId());
    }

    /**
     * 根据query取出一条记录，但是可能有多条记录，取最新的一条。
     *
     * @param query 查询条件 KV 格式
     * @return 实体对象
     */
    public LbsTrack selectObjByQuery(Query query) {
        if (query == null || query.size() == 0) {
            return null;
        }
        if (!query.containsKey("entId")) {
            query.put("entId", helpService.getEnterpriseId());
        }

        List<LbsTrack> list = selectByQuery(query);
        if (list == null || list.size() == 0) {
            return null;
        }

        return list.get(0);
    }

    /**
     * 根据条件获取List
     *
     * @param query 查询条件 KV 格式
     * @return 实体对象列表
     */
    public List<LbsTrack> selectByQuery(Query query) {
        if (!query.containsKey("deleteFlag")) {
            query.put("deleteFlag", 0);
        }
        if (!query.containsKey("entId")) {
            query.put("entId", helpService.getEnterpriseId());
        }

        return lbsTrackDao.selectByQuery(query);
    }

    /**
     * 根据条件获取记录总数
     *
     * @param query 查询条件 KV 格式
     * @return 总记录数
     */
    public Long countByQuery(Query query) {
        if (!query.containsKey("deleteFlag")) {
            query.put("deleteFlag", 0);
        }
        if (!query.containsKey("entId")) {
            query.put("entId", helpService.getEnterpriseId());
        }

        return lbsTrackDao.countByQuery(query);
    }

    /**
     * 根据ID删除记录信息
     *
     * @param id 主键id
     * @return True or False
     */
    public Boolean deleteById(Integer id) {
        return lbsTrackDao.deleteById(id, helpService.getEnterpriseId());
    }

    //region 获取轨迹信息，统一管理，三端通用

    /**
     * 获取轨迹，统一接口
     * 轨迹编码格式：[yyyyMMdd]-[ClientType]-[UserType]-[UserId]
     *
     * @param terminalCode 设备编码，格式不限
     * @param clientType   1PC/2WXAPP/3H5/4ANDROID/5IOS/6IPAD/7GPS/8POS
     * @param userType     1管理员/2司机/3会员/6车辆
     * @param entId        企业ID
     * @return map
     */
    public Map<String, Integer> getTraceKeyFromCache(String terminalCode, Integer clientType, Integer userType, Integer entId) {
        if (StringUtils.isBlank(terminalCode)) {
            return null;
        }

        if (entId == null || entId <= 0) {
            entId = helpService.getEnterpriseId();
        }

        //终端信息
        LbsTerminal terminal = lbsTerminalService.getByTerminalCodeFromCache(terminalCode, entId);
        if (terminal == null) {
            return null;
        }

        //根据客户端类型取值
        int _onlyid = terminal.getCarId();

        if (clientType <= 6) {
            _onlyid = terminal.getUserId();
        }

        //轨迹编码
        String trackCode = packageTrackCode(clientType, userType, _onlyid);

        Map<String, Integer> map = jedisCache.oget(KeyConstants.LBS_TRACKINFO_TACKCODE + trackCode + "_" + entId, Map.class);
        if (map == null) {
            map = getTraceKey(terminal, clientType, userType, entId);
            jedisCache.oset(KeyConstants.LBS_TRACKINFO_TACKCODE + trackCode + "_" + entId, map);
        }

        return map;
    }

    //获取轨迹相关信息，如果不存在则创建一条
    //轨迹编码格式：[yyyyMMdd]-[ClientType]-[UserType]-[UserId]
    //客户端类型：1PC/2WXAPP/3H5/4ANDROID/5IOS/6IPAD/7GPS/8POS
    //用户类型：1管理员/2司机/3会员/6车辆
    //如果是GPS，最后一位为CarId
    private Map<String, Integer> getTraceKey(LbsTerminal terminal, Integer clientType, Integer userType, Integer entId) {

        //根据客户端类型取值
        int _onlyid = 0;
        String _onlyname = "";

        if (clientType <= 6) { //如果是用户
            TransportUser user = userService.getFromCacheId(terminal.getUserId(), entId);
            if (user != null) {
                _onlyid = user.getId();
                _onlyname = user.getNickName();
            }
        }

        //轨迹编码
        String trackCode = packageTrackCode(clientType, userType, _onlyid);

        //查询轨迹是否已经存在，不存在则创建
        LbsTrack exist = getByTrackCode(trackCode, entId);

        if (exist == null) {
            exist = new LbsTrack();
            exist.setEntId(entId);
            exist.setServiceId(terminal.getServiceId());
            exist.setTerminalId(terminal.getId());
            exist.setUserId(terminal.getUserId());
            exist.setCarId(terminal.getCarId());
            exist.setTrackName(_onlyname + "（" + DateNomalUtils.datePath() + "）轨迹");
            exist.setTrackCode(trackCode);
            exist.setAdminId(0);
            exist.setCreateTime(new Date());
            exist.setStopFlag(0);
            exist.setDeleteFlag(0);
            exist = insert(exist);
        }

        //返回数据
        Map<String, Integer> map = new HashMap<>();
        map.put("serviceid", terminal.getServiceId());
        map.put("terminalid", terminal.getId());
        map.put("trackid", exist.getId());
        map.put("userid", terminal.getUserId());
        return map;
    }

    //组合编码
    public String packageTrackCode(Integer clientType, Integer userType, Integer onlyId) {
        return String.format("%s-%s-%s-%s", DateNomalUtils.datePath(), clientType, userType, onlyId);
    }

    //通过轨迹编码获取信息
    private LbsTrack getByTrackCode(String trackCode, Integer entId) {
        Query query = Query.noPage();
        query.put("entId", entId);
        query.put("trackCode", trackCode);
        query.put("stopFlag", 0);
        return selectObjByQuery(query);
    }
    //endregion
}